<?php

namespace app\model\store;

use app\base\BaseModel;
use app\libs\Aes;
use app\libs\AliyunSms;
use Firebase\JWT\JWT;
use think\facade\Config;
use think\model\concern\SoftDelete;

/**
 * 模型-权限用户
 * Class StoreAuthUserModel
 * @package app\model
 */
class StoreAuthUserModel extends BaseModel
{
    use SoftDelete;

    protected $name = 'store_auth_user';

    /**
     * 店铺id 查询范围
     * @param $query
     * @param $store_id
     */
    public function scopeStoreId($query, $store_id)
    {
        if (!empty($store_id)) {
            $query->alias("a");
            $query->where('a.store_id', $store_id);
        }
    }

    /**
     * 彻底删除
     * @param $id
     * @return bool
     * @throws \Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function delComplete($id)
    {
        $user = self::onlyTrashed()->find($id);
        StoreAuthGroupAccessModel::destroy(['user_id' => $id], true);
        return $user->force()->delete();
    }

    /**
     * 模型关联-角色中间表
     * @return \think\model\relation\HasOne
     */
    public function roleAccess()
    {
        return $this->hasOne(StoreAuthGroupAccessModel::class, 'user_id', 'id')->bind(['group_id']);
    }

    /**
     * 获取分页列表
     * @param $group_id
     * @param $status
     * @param $keyword
     * @param $current_page
     * @param $list_rows
     * @param $field
     * @param $store_id
     * @return array
     */
    public function getPageData($group_id, $status, $keyword, $current_page, $list_rows, $field="*", $store_id = '')
    {
        $map = [];
        $admin_name = Config::get('system.administrator');
        if (!empty($admin_name)) {
            array_push($map, ['a.username', '<>', $admin_name]);
        }
        if (!empty($group_id)) {
            array_push($map, ['b.group_id', '=', $group_id]);
        }
        if ($status != null) {
            array_push($map, ['a.status', '=', $status]);
        }
        if (!empty($keyword)) {
            array_push($map, ['a.realname', 'like', '%' . trim($keyword) . '%']);
        }
        $dataList = $this
            ->field($field)
            ->alias('a')
            ->storeId($store_id)
            ->leftJoin('t_store_auth_group_access b', 'b.user_id=a.id')
            ->leftJoin('t_store_auth_group c', 'c.id=b.group_id')
            ->leftJoin('t_store s', 's.id=a.store_id')
            ->where($map)
            ->order('a.create_time', 'desc')
            ->paginate(['page' => $current_page, 'list_rows' => $list_rows], false);
        $current = $dataList->currentPage();
        $total = $dataList->total();
        $limit = $dataList->listRows();
        $ret = ['total' => $total, 'current' => $current, 'limit' => $limit, 'dataList' => $dataList->items()];
        return $ret;
    }

    /**
     * 设置用户登录存储信息
     * @param $data
     * @param $suffix
     * @return mixed
     */
    public function setUserLoginStorage($data, $suffix = '_store')
    {
        $flag = $this->redis->hSet($this->redis_key . $suffix, $data['id'], serialize($data));
        $this->redis->expire($this->redis_key . $suffix, $data['expires_in']);
        return $flag;
    }

    /**
     * 获取用户登录存储信息
     * @param $user_id
     * @param $suffix
     * @return mixed
     */
    public function getUserLoginStorage($user_id, $suffix = '_store')
    {
        $data = $this->redis->hGet($this->redis_key . $suffix, $user_id);
        if ($data) {
            $data = unserialize($data);
        }
        return $data;
    }

    /**
     * 入口
     * @param $param
     * @return array
     */
    public function login($param)
    {
        try {
            $aes = new Aes();
            $param['password'] = $aes->decrypt($param['password']);
            $user = $this
                ->with(['roleAccess'])
                ->field('id,store_id,username,password,status')
                ->where('username', '=', $param['username'])
                ->find();

            if (empty($user)) {
                return ['code' => 2006];
            } else if (!password_verify($param['password'], $user['password'])) {
                return ['code' => 2007];
            } else {
                $admin_name = Config::get('system.administrator');
                if ($admin_name != $user['username']) {
                    if ($user['status'] == 0) {
                        return ['code' => 2008];
                    }
                    if (!empty($user['group_id'])) {
                        $db_auth_group = new StoreAuthGroupModel();
                        $role = $db_auth_group->getInfoByRedis($user['group_id'], 'id', '_store');
                        if ($role['status'] == 0) {
                            return ['code' => 2009];
                        }
                    } else {
                        return ['code' => 2009];
                    }
                }
                $token_set = Config::get('system.token_set');
                $jwtKey = Config::get('system.jwt_key');
                $access_token = JWT::encode(['user_id' => $user['id'], 'create_time' => time(), 'expires_in' => $token_set['admin']['access_expires'], 'type' => 'access'], $jwtKey);
                $refresh_token = JWT::encode(['user_id' => $user['id'], 'create_time' => time(), 'expires_in' => $token_set['admin']['refresh_expires'], 'type' => 'refresh'], $jwtKey);
                $this->setUserLoginStorage([
                    'id' => $user['id'],
                    'username' => $user['username'],
                    'realname' => $user['realname'],
                    'status' => $user['status'],
                    'group_id' => $user['group_id'],
                    'store_id' => $user['store_id'],
                    'expires_in' => $token_set['admin']['refresh_expires'],
                    'access_token' => $access_token,
                    'refresh_token' => $refresh_token
                ]);
                return ['code' => 1, 'data' => [
                    'access_token' => $access_token,
                    'group_id' => $user['group_id'],
                    'refresh_token' => $refresh_token
                ]];
            }
        } catch (\Exception $e) {
            return ['code' => 0, 'msg' => $e->getMessage()];
        }
    }

    /**
     * 手机号码+验证码登录
     * @param $param
     * @return array
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function loginPhone($param)
    {
        try {
            $phone = $param['phone'];
            $code = $param['code'];
            $return_data = AliyunSms::verifySms($phone, $code);
            if ($return_data['code'] != 1) {
                return $return_data;
            }
            $user = $this
                ->with(['roleAccess'])
                ->field('id,store_id,username,status')
                ->where('phone', '=', $phone)
                ->find();

            if (empty($user)) {
                return ['code' => 2006];
            } else {
                $admin_name = Config::get('system.administrator');
                if ($admin_name != $user['username']) {
                    if ($user['status'] == 0) {
                        return ['code' => 2008];
                    }
                    if (!empty($user['group_id'])) {
                        $db_auth_group = new StoreAuthGroupModel();
                        $role = $db_auth_group->getInfoByRedis($user['group_id'], 'id', '_store');
                        if ($role['status'] == 0) {
                            return ['code' => 2009];
                        }
                    } else {
                        return ['code' => 2009];
                    }
                }
                $token_set = Config::get('system.token_set');
                $jwtKey = Config::get('system.jwt_key');
                $access_token = JWT::encode(['user_id' => $user['id'], 'create_time' => time(), 'expires_in' => $token_set['admin']['access_expires'], 'type' => 'access'], $jwtKey);
                $refresh_token = JWT::encode(['user_id' => $user['id'], 'create_time' => time(), 'expires_in' => $token_set['admin']['refresh_expires'], 'type' => 'refresh'], $jwtKey);
                $this->setUserLoginStorage([
                    'id' => $user['id'],
                    'username' => $user['username'],
                    'realname' => $user['realname'],
                    'status' => $user['status'],
                    'group_id' => $user['group_id'],
                    'store_id' => $user['store_id'],
                    'expires_in' => $token_set['admin']['refresh_expires'],
                    'access_token' => $access_token,
                    'refresh_token' => $refresh_token
                ]);
                return ['code' => 1, 'data' => [
                    'access_token' => $access_token,
                    'group_id' => $user['group_id'],
                    'refresh_token' => $refresh_token
                ]];
            }
        } catch (\Exception $e) {
            return ['code' => 0, 'msg' => $e->getMessage()];
        }
    }

    /**
     * 添加店铺最高管理员
     * @param string $phone
     * @param string $store_id
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function addStoreManage($phone = '', $store_id = '')
    {
        if (empty($phone)) {
            return false;
        }
        $in_user = [
            'username' => $phone,
            'phone' => $phone,
            'store_id' => $store_id,
            'status' => 0,
        ];
        $user_data = $this->where('phone', $phone)->find();
        if (!empty($user_data)) {
            return false;
        } else {
            $in_user['id'] = $user_data['id'];
        }
        $ret = $this->saveData($in_user);
        if ($ret['flag']) {
            $user_id = $ret['id'];
            $db_access = new StoreAuthGroupAccessModel();
            $db_access->where('user_id', $user_id)->delete(true);
            $db_access->saveData([
                'user_id' => $user_id,
                'group_id' => 4,
                'store_id' => $store_id,
            ]);
            $this->delRedis($ret['id']);
            return true;
        }
        return false;
    }

    /**
     * 激活店铺管理员账号
     * @param $store_id
     * @return bool
     */
    public function activateManage($store_id)
    {
        $map = [
            'store_id' => $store_id
        ];
        $ret = $this->where($map)->update(['status' => 1]);
        if ($ret === false) {
            return false;
        }
        return true;
    }
}
